#region Using Statements
using System;
using System.IO;
using System.Collections.Generic;//using System.Xml.Serialization;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Storage;
#endregion

namespace Pauliver
{
    public class RecentLevelSelection : BaseMenu
    {
        TerrainSaver ts;
        Texture2D MiniMap;
        Texture2D Minimap_overlay;
        Texture2D Select_level;

        Triplet<Team, PlayerIndex, TeamType>[] teams;

        LinkedList<TerrainSaver> LL;
        LinkedListNode<TerrainSaver> CurrentNode;
        bool ShowingNode = false;
        public RecentLevelSelection(Triplet<Team, PlayerIndex, TeamType>[] p_teams)
            : base()
        {
            // Store the teams
            teams = p_teams;
            // Load the MiniMap texture
            MiniMap = PContentManager.Instance.GetObject<Texture2D>("MiniMap");
            Minimap_overlay = PContentManager.Instance.GetObject<Texture2D>(@"Content/Art/GUI/Minimap_overlay");
            Select_level = PContentManager.Instance.GetObject<Texture2D>(@"Content/Art/GUI/Select_level");
            // Generate Terrain

            //create the menu
            _menu = new UIBaseMenu(@"Content/Art/GUI/MenuBackground", Vector2.Zero);

            //Now create buttons
            UIButton b = new UIButton(@"Content/Art/GUI/Start", new Vector2(20, 175));
            _menu.Add(SelectMap, b);

            StorageDevice storageDevice = Game1.Instance.StorageDevice;
            StorageContainer storageContainer = storageDevice.OpenContainer("Name");
            string filename = Path.Combine(storageContainer.Path, "PreviouslyPlayed.txt");
            FileStream stream = File.Open(filename, FileMode.OpenOrCreate, FileAccess.Read);
            StreamReader sr = new StreamReader(stream);
            LL = new LinkedList<TerrainSaver>();
            while (!sr.EndOfStream)
            {
                TerrainSaver ts = new TerrainSaver();
                if (ts.Read(sr))
                    LL.AddLast(ts);
            }
            stream.Close();
            storageContainer.Dispose();
            ShowingNode = true;
            CurrentNode = LL.First;

            GenerateTerrain();

            b = new UIButton(@"Content/Art/GUI/Next", new Vector2(219, 115));
            _menu.Add(NextMap, b);

            b = new UIButton(@"Content/Art/GUI/Previous", new Vector2(-20, 115));
            _menu.Add(PreviousMap, b);


            b = new UIButton(@"Content/Art/GUI/Back", new Vector2(20, 280));
            _menu.Add(Back, b);


            _menu.Setup();
        }

        protected void GenerateTerrain()
        {
#if WINDOWS
            GraphicsDevice gd = MiniMap.GraphicsDevice;
            int height = MiniMap.Height;
            int width = MiniMap.Width;
            MiniMap.Dispose();

            MiniMap = new Texture2D(gd, width, height);
            PContentManager.Instance.SaveContent<Texture2D>(MiniMap, "MiniMap");
#endif

            int s_hr = ts.Square_Height;
            int s_wr = ts.Square_Width;
            int t_hr = ts.Triangle_Height;
            int t_wr = ts.Triangle_Width;
            int n1_hr = ts.Noise1_Height;
            int n1_wr = ts.Noise1_Width;
            int n2_hr = ts.Noise2_Height;
            int n2_wr = ts.Noise2_Width;
            int offset = ts.Offset_From_Zero;
            float pi = 3.14159265f;

            int EdgeOffset = Terrain.EdgeOffset;

            Color[] MiniColorData = new Color[MiniMap.Height * MiniMap.Width];
            MiniMap.GetData<Color>(MiniColorData);
            for (int i = (0 + offset + EdgeOffset); i < ((MiniMap.Width * 10) + offset + EdgeOffset); i += 10)
            {
                int square_height = 75 + s_hr, square_width = 10 + s_wr;
                double square = ((square_height) * (Math.Sin((double)0.01 / square_width * 2 * pi * i))) + ((square_height / 3) * (Math.Sin((double)0.01 / square_width * 6 * pi * i))) + ((square_height / 5) * (Math.Sin((double)0.01 / square_width * 10 * pi * i))) + ((square_height / 7) * (Math.Sin((double)0.01 / square_width * 14 * pi * i))) + ((square_height / 9) * (Math.Sin((double)0.01 / square_width * 18 * pi * i)));

                int triangle_height = 100 + t_hr, triangle_width = 8 + t_wr;
                double triangle = (((triangle_height) * (Math.Sin((double)(0.01 / triangle_width) * 2 * pi * i))) - ((triangle_height / 9) * (Math.Sin((double)(0.01 / triangle_width) * 6 * pi * i))) + ((triangle_height / 25) * (Math.Sin((double)(0.01 / triangle_width) * 10 * pi * i))));

                int sine_height = -50 + n1_hr, sine_width = 40 + n1_wr;
                double sine = ((sine_height) * (Math.Sin((double)(0.01 / sine_width) * 2 * pi * i)));

                int noise_height = -25 + n2_hr, noise_width = 20 + n2_wr;
                double noise = ((noise_height) * (Math.Cos((double)(0.1 / noise_width) * 2 * pi * i)));

                double piece6 = 500;
                double temp = square + triangle + sine + noise + piece6;
                for (int j = 0; j < (MiniMap.Height * 10); j += 10)
                {
                    int index = ((i - offset - EdgeOffset) / 10) + (j * MiniMap.Width / 10);
                    if (j > temp)
                    {
                        MiniColorData[index] = Color.Black; //255 means no alpha
                    }
                    else
                    {
                        MiniColorData[index] = new Color(255, 255, 255, 255);
                    }
                }
            }
            MiniMap.SetData<Color>(MiniColorData);
            System.GC.Collect();
        }

        public override void Update(GameTime p_Time)
        {
            _menu.Update();
            _menu.ProcessInput(PlayerIndex.One); //only uncomment me if there are buttons
        }
        public override void ProccessInput(PlayerIndex p_index)
        {
            _menu.ProcessInput(p_index);
        }
        public override void Draw(SpriteBatch p_spriteBatch, GameTime p_Time)
        {
            _menu.Draw(p_spriteBatch, p_Time);
            p_spriteBatch.Draw(Select_level, new Vector2(20, 56), null, Color.White, 0.0f, Vector2.Zero, 1.0f, SpriteEffects.None, DrawLayer.GetLayer(DrawLayer.LayerDepth.MenuButton));
            p_spriteBatch.Draw(Minimap_overlay, new Vector2(20, 86), null, Color.White, 0.0f, Vector2.Zero, 1.0f, SpriteEffects.None, DrawLayer.GetLayer(DrawLayer.LayerDepth.MenuButton));
            p_spriteBatch.Draw(MiniMap, new Vector2(24, 96), null, Color.White, 0.0f, Vector2.Zero, 1.0f, SpriteEffects.None, DrawLayer.GetLayer(DrawLayer.LayerDepth.BetweenMenu));
        }



        protected void SelectMap()
        {
            Game1.Instance.PopTopMenu();
            Game1.Instance.LoadGame(teams, ts);
        }

        protected void NextMap()
        {
            if (ShowingNode)
            {
                if (CurrentNode == LL.Last)
                {
                    CurrentNode = LL.First;
                }
                else
                {
                    CurrentNode = CurrentNode.Next;
                }
            }
            else
            {
                ShowingNode = true;
            }
            ts = CurrentNode.Value;
            GenerateTerrain();
        }
        protected void PreviousMap()
        {
            if (ShowingNode)
            {
                if (CurrentNode == LL.First)
                {
                    CurrentNode = LL.Last;
                }
                else
                {
                    CurrentNode = CurrentNode.Previous;
                }
            }
            else
            {
                ShowingNode = true;
            }
            ts = CurrentNode.Value;
            GenerateTerrain();

        }
        public override void Back()
        {
            Game1.Instance.PopTopMenu();
            Game1.Instance.AddMenu(new LevelSelection(teams));
        }
    }
}